home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------
-
- collapse.c
-
- This module handles collapsing and expanding threads.
-
- Copyright © 1994-1995, Northwestern University.
-
- ----------------------------------------------------------------------------*/
-
- #include "glob.h"
- #include "collapse.h"
- #include "menus.h"
- #include "newswatcher.h"
- #include "windutil.h"
- #include "dialog.h"
- #include "listutil.h"
- #include "help.h"
-
-
-
-
- /*----------------------------------------------------------------------------
- ExpandCollapseThread
-
- Expand or collapse a single thread.
-
- Entry: wind = pointer to subject window.
- theCell = any cell in the thread to be expanded or collapsed.
-
- Exit: function result = true if thead collapsed, false if expanded.
- ----------------------------------------------------------------------------*/
-
- Boolean ExpandCollapseThread (WindowPtr wind, Cell theCell)
- {
- TWindow **info;
- ListHandle theList;
- TSubject **subjectArray, theSubject;
- Cell tmpCell, newCell;
- long finalTicks;
- short i, nextInThread, cellDataLen, index;
- Rect inval;
- short visTopBeforeDelRow, visTopAfterDelRow;
-
- KillBalloon();
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- subjectArray = (**info).subjectArray;
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- theSubject = (*subjectArray)[index];
- if (theSubject.threadOrdinal != 1) {
- theCell.v -= theSubject.threadOrdinal-1;
- LGetCell(&index, &cellDataLen, theCell, theList);
- theSubject = (*subjectArray)[index];
- }
- theSubject.collapsed = !theSubject.collapsed;
- nextInThread = index;
- for (i = 0; i < theSubject.threadLength; i++) {
- (*subjectArray)[nextInThread].collapsed = theSubject.collapsed;
- nextInThread = (*subjectArray)[nextInThread].nextInThread;
- }
- (*subjectArray)[index].onlyRedrawTriangle = true;
- (*subjectArray)[index].onlyRedrawCheck = false;
- (*subjectArray)[index].drawTriangleFilled = true;
- LDraw(theCell, theList);
- (*subjectArray)[index].onlyRedrawTriangle = false;
- (*subjectArray)[index].onlyRedrawCheck = true;
- LDraw(theCell, theList);
- (*subjectArray)[index].onlyRedrawTriangle = true;
- (*subjectArray)[index].onlyRedrawCheck = false;
-
- if (theSubject.collapsed) {
- visTopBeforeDelRow = (**theList).visible.top;
- LDelRow(theSubject.threadLength-1, theCell.v+1, theList);
- visTopAfterDelRow = (**theList).visible.top;
- if (visTopBeforeDelRow != visTopAfterDelRow)
- (*subjectArray)[index].onlyRedrawTriangle = false;
- SetPt(&tmpCell, 0, 0);
- if (!LGetSelect(true, &tmpCell, theList))
- MyLSetSelect(true, theCell, theList);
- } else {
- LSetDrawingMode(false, theList);
- LAddRow(theSubject.threadLength-1, theCell.v+1, theList);
- newCell = theCell;
- nextInThread = theSubject.nextInThread;
- for (i = 1; i < theSubject.threadLength; i++) {
- newCell.v++;
- LSetCell(&nextInThread, 2, newCell, theList);
- nextInThread = (*subjectArray)[nextInThread].nextInThread;
- }
- LSetDrawingMode(true, theList);
- inval = wind->portRect;
- inval.top = (**info).panelHeight + (theCell.v - (**theList).visible.top + 1) *
- (**theList).cellSize.v;
- inval.right -= 15;
- inval.bottom -= 15;
- InvalRect(&inval);
- }
-
- Delay(8, &finalTicks);
- (*subjectArray)[index].drawTriangleFilled = false;
- LDraw(theCell, theList);
- (*subjectArray)[index].onlyRedrawTriangle = false;
- return theSubject.collapsed;
- }
-
-
-
- /*----------------------------------------------------------------------------
- RezoomSubjectWindow
-
- Rezoom a subject window after a thread has been expanded if the
- "Zoom windows" preference is turned on and the window is
- not locked.
-
- Entry: wind = pointer to subject window.
- expanded = true if thread expanded, false if contracted.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr RezoomSubjectWindow (WindowPtr wind, Boolean expanded)
- {
- TWindow **info;
- ListHandle theList;
- ControlHandle scrollBar;
- OSErr err = noErr;
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- scrollBar = (**theList).vScroll;
- if (expanded && gPrefs.reZoomWindows &&
- GetControlMaximum(scrollBar) > 0 && !(**info).windPosLocked)
- {
- err = DoZoom(wind, inZoomOut);
- if (err != noErr) return err;
- } else {
- SetWindowNeedsZooming(wind);
- }
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoExpandCollapseSelectedThread
-
- Expand or collapse just the currently selected thread.
-
- Entry: wind = pointer to subject window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr DoExpandCollapseSelectedThread (WindowPtr wind)
- {
- TWindow **info;
- ListHandle theList;
- TSubject **subjectArray;
- Cell theCell, tmpCell;
- short cellDataLen, index;
- TSubject theSubject;
- Boolean collapsed;
- OSErr err = noErr;
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- subjectArray = (**info).subjectArray;
- SetPt(&theCell, 0, 0);
- if (!LGetSelect(true, &theCell, theList)) return noErr;
- tmpCell = theCell;
- tmpCell.v++;
- if (LGetSelect(true, &tmpCell, theList)) return noErr;
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- theSubject = (*subjectArray)[index];
- if (theSubject.threadLength <= 1) return noErr;
- collapsed = ExpandCollapseThread(wind, theCell);
- err = RezoomSubjectWindow(wind, !collapsed);
- if (err != noErr) return err;
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- TriangleClick
-
- Handle a click on a triangle thread control.
-
- Entry: wind = pointer to subject window.
- where = location of mouse down in local coordinates.
-
- Exit: function result = error code.
- *triangleClicked = true if triangle control clicked.
- ----------------------------------------------------------------------------*/
-
- OSErr TriangleClick (WindowPtr wind, Point where, Boolean *triangleClicked)
- {
- TWindow **info;
- ListHandle theList;
- TSubject **subjectArray, theSubject;
- FontInfo fontInfo;
- Cell theCell;
- short index, cellDataLen;
- Rect hitRect;
- Boolean inHitRect, newInHitRect;
- short visTop, cellHeight;
- Boolean collapsed;
- short panelHeight;
- OSErr err = noErr;
-
- *triangleClicked = false;
- info = (TWindow**)GetWRefCon(wind);
- panelHeight = (**info).panelHeight;
- theList = (**info).theList;
- visTop = (**theList).visible.top;
- cellHeight = (**theList).cellSize.v;
- subjectArray = (**info).subjectArray;
- GetFontInfo(&fontInfo);
- SetRect(&hitRect, 0, 0, (**theList).indent.h + fontInfo.ascent, 0);
- if (where.h > hitRect.right) return noErr;
- if (!PtInListCell(where, theList)) return noErr;
- theCell.h = 0;
- theCell.v = (where.v - panelHeight)/cellHeight + visTop;
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- theSubject = (*subjectArray)[index];
- if (theSubject.threadLength == 1 || theSubject.threadOrdinal > 1)
- return noErr;
- (*subjectArray)[index].drawTriangleFilled = inHitRect = true;
- (*subjectArray)[index].onlyRedrawTriangle = true;
- LDraw(theCell, theList);
- hitRect.top = (theCell.v - visTop) * cellHeight + panelHeight;
- hitRect.bottom = hitRect.top + cellHeight;
- while (StillDown()) {
- GetMouse(&where);
- newInHitRect = PtInRect(where, &hitRect);
- if (newInHitRect != inHitRect) {
- (*subjectArray)[index].drawTriangleFilled = newInHitRect;
- LDraw(theCell, theList);
- inHitRect = newInHitRect;
- }
- }
- if (!inHitRect) {
- (*subjectArray)[index].drawTriangleFilled = false;
- (*subjectArray)[index].onlyRedrawTriangle = false;
- return noErr;
- }
- collapsed = ExpandCollapseThread(wind, theCell);
- err = RezoomSubjectWindow(wind, !collapsed);
- if (err != noErr) return err;
- *triangleClicked = true;
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- ExpandCollapseKey
-
- Handle the Command-arrow key shortcuts for exanding and collapsing threads.
-
- Entry: wind = pointer to subject window.
- theChar = the character (left or right arrow).
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr ExpandCollapseKey (WindowPtr wind, char theChar)
- {
- TWindow **info;
- ListHandle theList;
- TSubject **subjectArray;
- Cell theCell, cellToScrollIntoView;
- short cellDataLen, index;
- TSubject theSubject;
- Boolean expand;
- Boolean changed = false;
- OSErr err = noErr;
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- subjectArray = (**info).subjectArray;
- expand = theChar == rightArrow;
-
- SetPt(&theCell, 0, 0);
- SetPt(&cellToScrollIntoView, 0, 0);
- while (true) {
- if (!LGetSelect(true, &theCell, theList)) break;
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- theSubject = (*subjectArray)[index];
- if (theSubject.threadLength > 1)
- if (theSubject.collapsed && expand ||
- !theSubject.collapsed && !expand)
- {
- ExpandCollapseThread(wind, theCell);
- if (!expand) {
- if (cellToScrollIntoView.v == 0 &&
- theCell.v >= (**theList).visible.top &&
- theCell.v < (**theList).visible.bottom)
- {
- cellToScrollIntoView.v = theCell.v - theSubject.threadOrdinal + 1;
- }
- theCell.v -= theSubject.threadOrdinal - 1;
- }
- if (!changed) changed = true;
- }
- theCell.v++;
- }
- if (changed) {
- err = RezoomSubjectWindow(wind, expand);
- if (err != noErr) return err;
- if (cellToScrollIntoView.v != 0)
- MyLScrollCellIntoView(cellToScrollIntoView, theList);
- }
- return noErr;
- }
-